use std::os::unix::net::{UnixListener, UnixStream};
use std::io::{Read, Write};
use std::fs;

const SOCKET_NAME: &str = "/tmp/DemoSocket";
const BUFFER_SIZE: usize = 128;

fn handle_client(mut stream: UnixStream) {
    let mut result: i32 = 0;
    loop {
        let mut buffer = [0; BUFFER_SIZE];
        
        println!("Waiting for data from the client");
        match stream.read(&mut buffer) {
            Ok(0) => {
                // End of stream.
                break;
            }
            Ok(_) => {
                let data = i32::from_ne_bytes(buffer[..4].try_into().unwrap());
                if data == 0 {
                    break;
                }
                result += data;
            }
            Err(e) => {
                eprintln!("Error reading from socket: {}", e);
                return;
            }
        }
    }

    // Send result.
    println!("Sending final result back to client");
    let response = format!("Result = {}", result);
    if let Err(e) = stream.write_all(response.as_bytes()) {
        eprintln!("Error writing to socket: {}", e);
    }
}

fn main() -> std::io::Result<()> {
    fs::remove_file(SOCKET_NAME).ok(); // Ignore error if file doesn't exist.

    let listener = UnixListener::bind(SOCKET_NAME)?;

    println!("Server is listening on {}", SOCKET_NAME);

    // Main loop for accepting connections.
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                println!("Connection accepted from client");
                handle_client(stream);
            }
            Err(e) => {
                eprintln!("Error accepting connection: {}", e);
            }
        }
    }

    fs::remove_file(SOCKET_NAME)?; // Clean up the socket file.

    Ok(())
}
